package steffen;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Klasse, um aus einzelnen ausführbaren Menüpunkten ein gesamten funktionales Menü zu generieren.
 * 
 * @author Steffen Krüger
 * @version 1.0
 * 
 * @see Menüpunkt
 */
public class Menü extends Menüpunkt
{
    /**
     * Vorgegebene Methode zum Beenden des Programms
     */
    private static final Menüpunkt quit = new Menüpunkt("Beenden", new Runnable()
    {
        public void run()
        {
            System.out.println("Bye!");
            System.exit(0);
        }
    });
    
    /**
     * Vorgegebene Methode um in das übergeordnete Menü zu springen
     */
    private static final Menüpunkt back = new Menüpunkt("Zurück");

    /**
     * Arrayliste mit Menüpunkten und Untermenüs
     */
    List<Menüpunkt> items;
    
    /**
     * Konstuktor für das Hauptmenü
     * @param title Titel des Menüs
     * @param items Menüpunkte und/oder Untermenüs
     */
    public Menü(String title, Menüpunkt... items)
    {
        this(title, false, true, items);
    }

    /**
     * 
     * @param title
     * @param addBack
     * @param addQuit
     * @param items
     */
    public Menü(String title, boolean addBack, boolean addQuit, Menüpunkt... items)
    {
        super(title);
        setExec(this);

        initialize(addBack, addQuit, items);
    }
    
    /**
     * 
     * @param addBack
     * @param addQuit
     * @param items
     */
    private void initialize(boolean addBack, boolean addQuit, Menüpunkt... items)
    {
        this.items = new ArrayList<Menüpunkt>(Arrays.asList(items));
        if(addBack)
        {
            this.items.add(back);
        }
            
        if(addQuit)
        {
            this.items.add(quit);
        }
    }

    /**
     * 
     */
    private void display()
    {
        int option = 0;
        System.out.println("****** " + getTitel() + " ******\n");
        for (Menüpunkt item : items)
        {
            System.out.println((option++) + ": " + item.getTitel());
        }
        System.out.print("\nBitte wählen Sie: ");
        System.out.flush();
    }
    
    /**
     * 
     * @return
     * @throws IOException
     */
    private Menüpunkt prompt() throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        while (true)
        {
            display();

            String line = br.readLine();
            try
            {
                int option = Integer.parseInt(line);
                if (option >= 0 && option < items.size())
                {
                    System.out.println("\n");
                    return items.get(option);
                }
            } catch (NumberFormatException e)
            {
            }

            System.out.println("\nBitte geben Sie eine Zahl von 0 bis " + (items.size()-1) + " ein. Ihre Eingabe war: " + line + "\n");
        }
    }

    /**
     * Implementation von Runnable
     * Führt das Menü solange aus, bis es durch die Option beenden beendet wird
     */
    public void run()
    {
        try
        {
            for( Menüpunkt item = prompt(); item.isExec(); item = prompt() )
            {
                item.run();
            }
        } catch (Throwable t)
        {
            t.printStackTrace(System.out);
        }
    }
}